<?php


namespace app\common\controller;


use app\BaseController;
use app\common\model\Attachment;
use app\common\model\Config as configModel;
use think\Exception;
use think\exception\HttpResponseException;
use think\exception\ValidateException;
use think\facade\View;
use think\helper\Str;
use think\Response;
use think\facade\Db;
class Base extends BaseController
{

    public $view_path; // 前端模板路径
    public $Config;  // Config 表里的配置信息
    protected $controller;
    protected $page;
    protected $limit;
    protected $data;
    protected $order;
    protected $doValidate;
    public function initialize()
    {
        parent::initialize(); // TODO: Change the autogenerated stub
        $this->request->filter('app\common\helper\StringHelper::filterWords,trim');
    
        $this->controller = $this->request->controller();

        if (strpos($this->controller,".")) {
            $this->controller = str_replace(".","\\",$this->controller);
        }


        $this->page = input('page/d',1);
        $this->limit = input("limit/d",10);

        $this->data = input();
        $this->data['limit'] = empty($this->limit) ? 10 : $this->limit;
        $this->data['page'] = empty($this->page) ? 1 : $this->page;
        // 写入缓存
        $global = cache('config');
        if (empty($global)) {
            $result = configModel::select();
            $data = [];
            foreach ($result as $val) {
                $data[$val['key']] = $val['value'];
            }
            cache('config', $data);
            $global = $data;
        }
        $this->Config = $global;
        View::assign('config', $global);

        // 前端模板路径
        $view_path = 'htcms';
        $this->view_path = "../view/" . trim($view_path,'/\\ ') . "/";

    }

    // 重定向
    protected function redirect($url, $params = [], $code = 302, $with = [])
    {
        $response = Response::create($url, 'redirect');

        if (is_integer($params)) {
            $code = $params;
            $params = [];
        }

        $response->code($code)->with($params);

        throw new HttpResponseException($response);
    }

    protected function jump_success($msg = '', string $url = null, $data = '', int $wait = 3, array $header = [])
    {
        if (is_null($url) && isset($_SERVER["HTTP_REFERER"])) {
            $url = $_SERVER["HTTP_REFERER"];
        } elseif ($url) {
            $url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : app('route')->buildUrl($url);
        }

        $result = [
            'code' => 1,
            'msg' => $msg,
            'data' => $data,
            'url' => $url,
            'wait' => $wait,
        ];

        $type = $this->getResponseType();
        if ($type == 'html') {
            $response = view($this->app->config->get('app.dispatch_success_tmpl'), $result);
        } else if ($type == 'json') {
            $response = json($result);
        }
        throw new HttpResponseException($response);
    }

    protected function jump_error($msg = '', string $url = null, $data = '', int $wait = 3, array $header = [])
    {
        if (is_null($url)) {
            $url = $this->request->isAjax() ? '' : 'javascript:history.back(-1);';
        } elseif ($url) {
            $url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : $this->app->route->buildUrl($url);
        }

        $result = [
            'code' => 0,
            'msg' => $msg,
            'data' => $data,
            'url' => $url,
            'wait' => $wait,
        ];

        $type = $this->getResponseType();
        if ($type == 'html') {
//            $response = view($this->app->config->get('app.dispatch_error_tmpl'), $result);
            $response = view($this->app->config->get('app.layui_error_tmpl'), $result);
        } else if ($type == 'json') {
            $response = json($result);
        }
        throw new HttpResponseException($response);
    }

    /**
     * 获取当前的response 输出类型
     * @access protected
     * @return string
     */
    protected function getResponseType()
    {
        return $this->request->isJson() || $this->request->isAjax() ? 'json' : 'html';
    }

    public function upload()
    {
        if (!session("?user") && !session("?admin")) {
            return $this->error();
        }
        $type = input('get.type/s', 'allimg');
        try {
            $file = $_FILES["file"];
            if (!$file) {
                return $this->error("请选择文件");
            }
            if ($file["size"] > 1024*1024*20) { // 20M
                return $this->error("文件不能大于20M");
            }
            if (!is_dir('uploads')) mkdir('uploads');
            $ext = strtolower(strrchr($file["name"],"."));
            if (!is_dir('uploads/' . $type)) {
                mkdir('uploads/' . $type);
            }
            $path = "uploads/" . $type . "/" . date('Ym');
            if (!is_dir($path)) {
                mkdir($path);
            }
            $name = md5(time() . Str::random(6)) . $ext;
            $name = $path . "/" . $name;
            $allows = ".jpg,.bmp,.gif,.png,.webp,.jpeg,.zip,.rar,.pdf,.xls,.xlsx,.gz,.doc,.docx,.mp3,.mp4";
            $allows = explode(",",$allows);
            if (!in_array($ext,$allows)) {
                return $this->error("不允许上传的文件类型。");
            }

            if (!move_uploaded_file($file["tmp_name"],$name)) {
                return $this->error("上传失败");
            }

            Attachment::create([
               "path" => "/".$name,
                "name" => $file["name"],
                "size" => $file["size"],
                "type" => $file["type"],
                "ext" => $ext,
                "admin_id" => session("admin.id") ?? 0
            ]);

            return  json(["code"=>1,"url"=>"/".$name]);

        } catch (Exception $exception) {
            return  $this->error($exception->getMessage());
        }
    }

    protected function success($data = [],$msg = '操作成功') {
        if (is_string($data)) {
            $msg = $data;
            $data = '';
        }
        $res = ['code'=>1,'msg'=>$msg,'data'=>$data];
        throw new HttpResponseException(json($res));
    }
    protected function error($data=[],$msg = '操作失败') {
        if (is_string($data)) {
            $msg = $data;
            $data = '';
        }
        $res = ['code'=>0,'msg'=>$msg,'data'=>$data];
        throw new HttpResponseException(json($res));
    }
    
    public function index()
    {
        if ($this->request->isPost()) {
            $where = $this->formatSearchKey();
            $funWhere = $this->where;
            if (!$this->order) $this->order = 'id desc';
            $list = $this->model
                ->where($where)
                ->with($this->with)
                ->where($funWhere)
                ->order($this->order)
                ->hidden(['password'])
                ->paginate(['list_rows'=>$this->limit,'page'=>$this->page]);
            $this->successData($list);
        }
        return View::fetch();
    }

    public function add()
    {
        $this->needLogin();
        if ($this->request->isPost()) {
            $data = input();
            if ($this->doValidate && class_exists($this->doValidate)) {
                try {
                    validate($this->doValidate)
                        ->scene('add')
                        ->check($data);
                } catch (ValidateException $exception) {
                    $this->error($exception->getMessage());
                }
            }
            if (isset($data['password'])) {
                if (!empty($data['password'])) {
                    $data['password'] = password_hash($data['password'],PASSWORD_DEFAULT);
                } else {
                    unset($data['password']);
                }
            }
            Db::startTrans();
            try {
                if (!empty($data['id'])) {
                    $obj = $this->model->find($data['id']);
                    $obj->save($data);
                } else {
                    $data['admin_id'] = session('admin.id');
                    $data['diggings_id'] = session('admin.diggings_id');
                    $this->model->save($data);
                }
                Db::commit();
                $this->successData();
            } catch (Exception $exception) {
                Db::rollback();
                $this->error($exception->getMessage());
            }
        }
        return View::fetch();
    }

    public function edit()
    {
        $this->needLogin();
        if ($this->request->isPost()) {
            $data = input();
            if ($this->doValidate && class_exists($this->doValidate)) {
                try {
                    validate($this->doValidate)
                        ->scene('edit')
                        ->check($data);
                } catch (ValidateException $exception) {
                    $this->error($exception->getMessage());
                }
            }
    
            if (isset($data['password'])) {
                if (!empty($data['password'])) {
                    $data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
                } else {
                    unset($data['password']);
                }
            }
            Db::startTrans();
            try {
                if (!empty($data['id'])) {
                    $obj = $this->model->find($data['id']);
                    $obj->save($data);
                } else {
                    $this->model->save($data);
                }
                Db::commit();
                $this->success();
            } catch (Exception $exception) {
                Db::rollback();
                $this->error($exception->getMessage());
            }
        }
        return View::fetch();
    }
    public function del()
    {
        $this->needLogin();
        if ($this->request->isPost()) {
            $ids = input("id");
            $this->model->where('id','in',$ids)
                ->where($this->where)
                ->delete();
            $this->success();
        }
    }

    public function all()
    {
        if ($this->request->isPost()) {
            $where = $this->formatSearchKey();
            if (!$this->order) $this->order = 'id desc';
            $list = $this->model->where($where)
                ->where($this->where)
                ->with($this->with)
                ->order($this->order)
                ->hidden(['password'])
                ->select();
            $this->success($list);
        }
    }

    public function detail()
    {
        $where = $this->formatSearchKey();
        $obj = $this->model->where($where)->where($this->where)
            ->with($this->with)->find();
        $this->success($obj);
    }

    public function setStatus()
    {
        $this->needLogin();
        $data = input();
        if ($this->request->isPost()) {
            if (!empty($data['id'])) {
                $u = $this->model->where('id',$data['id'])->find();
                $u->save(['status'=>$data['status']]);
                $this->success();
            }
        }
        return View::fetch();
    }


    protected function formatSearchKey()
    {
        $data = input('search_key');
        $type = input('search_type');
        $hide = input('search_hide',[]);
        if (empty($data)) return [];
        $where = [];
        foreach ($data as $key => $value) {
            if ((empty($value) && $value != 0) || $value === 'all' || in_array($key,$hide)) {
                continue;
            }
            if (!isset($type[$key])) {
                $where[] = [$key,"=",$value];
                continue;
            }
            switch (strtolower($type[$key])) {
                case "=":
                    $where[] = [$key,"=",$value];
                    break;
                case ">":
                    $where[] = [$key,">",$value];
                    break;
                case "<":
                    $where[] = [$key,"<",$value];
                    break;
                case "like":
                    $where[] = [$key,"like","%{$value}%"];
                    break;
                case "in":
                    $where[] = [$key,"in",$value];
                    break;
                case "between":
                    $where[] = [$key,"between",$value];
                    break;
                case "between time":
                    $where[] = [$key,"between",[strtotime($value[0]),strtotime($value[1]. " 23:59:59")]];
                    break;
                case "day":
                    $where[] = [$key,"between time",[$value,$value . " 23:59:59"]];
                    break;
                default:
                    $where[] = [$key,"=",$value];
            }
        }
        return $where;
    }

    protected function successData($data='',$msg = '操作成功')
    {
        $this->success($data,$msg);
    }

    protected function needLogin()
    {
        $token = $this->request->header('token');
        if (!session("?user") && !session("?admin") && !$token) {
            $this->error();
        }
    }
}
